/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hhf.worldzones.jmx;

import hhf.jmx.JMXManaged;
import hhf.resourceBundle.BundleName;
import hhf.worldzones.daos.CityDAO;
import hhf.worldzones.daos.ContinentDAO;
import hhf.worldzones.daos.CountryDAO;
import hhf.worldzones.daos.RegionDAO;
import hhf.worldzones.entities.Continent;
import hhf.worldzones.entities.Country;
import hhf.worldzones.entities.Region;
import hhf.worldzones.exceptions.EntityUnknownException;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.StringTokenizer;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.ScheduleExpression;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerConfig;
import javax.ejb.TimerService;
import javax.inject.Inject;
import org.slf4j.Logger;

/**
 *
 * @author François
 */
@Singleton
@JMXManaged
@Startup
public class Initialization implements InitializationMXBean {

	@EJB
	private ContinentDAO continentdao;
	@EJB
	private CountryDAO countrydao;
	@EJB
	private RegionDAO regiondao;
	@EJB
	private CityDAO citydao;
	@Inject
	Logger logger;

	@Inject @BundleName("initResources/ContinentCodes-ContinentLabels")
	ResourceBundle continentInfos;

	@Inject @BundleName("initResources/CountryCodes-CountryLabels")
	ResourceBundle countryInfos;

	@Inject @BundleName("initResources/CountryCodes-ContinentCodes")
	ResourceBundle countryContinent;

	@Inject @BundleName("initResources/CountryCodes-latitude-longitude")
	ResourceBundle countryGPS;

	@Inject @BundleName("initResources/CountryCodes-RegionCodes-RegionLabels")
	ResourceBundle regionInfos;

	@Inject @BundleName("initResources/CityIds-CoutryCodes-RegionCodes-CityLabels-postalCodes-long-lat")
	ResourceBundle cityInfos;

	@Override
	public String initAll() {
		logger.info("Initialisation de tout.");
		long t0 = System.currentTimeMillis();
		initContinents();
		initCountries();
		initRegions();
		initCities();
		return "tps : "+(System.currentTimeMillis()-t0)+"ms";
	}

	@Override
	public String initContinents() {
		logger.info("Initialisation des continents");
		long t0 = System.currentTimeMillis();
		for (String key : continentInfos.keySet()) {
			continentdao.createContinent(key, continentInfos.getString(key));
		}
		return "tps : "+(System.currentTimeMillis()-t0)+"ms";
	}

	@Override
	public String initCountries() {
		logger.info("Initialisation des countries");
		long t0 = System.currentTimeMillis();
		for (String key : countryInfos.keySet()) {
			Continent cont = null;
			Integer latitude = null;
			Integer longitude = null;
			try {
				cont = continentdao.find(countryContinent.getString(key));
			} catch (MissingResourceException mre) {
			} catch (EntityUnknownException cue1) {
				logger.error(cue1.getMessage());
			}
			try {
				String gps = countryGPS.getString(key);
				StringTokenizer st = new StringTokenizer(gps, ",");
				latitude = Integer.parseInt(st.nextToken().replaceAll("\\.", ""));
				longitude = Integer.parseInt(st.nextToken().replaceAll("\\.", ""));
			} catch (MissingResourceException mre) {
			}
			countrydao.createCountry(key, countryInfos.getString(key), cont, latitude, longitude);
		}
		return "tps : "+(System.currentTimeMillis()-t0)+"ms";
	}

	@Override
	public String initRegions() {
		logger.info("Initialisation des regions");
		long t0 = System.currentTimeMillis();
		for (String key : regionInfos.keySet()) {
			StringTokenizer st = new StringTokenizer(key, ",");
			String countryCode = st.nextToken();
			Country country = null;
			try {
				country = countrydao.find(countryCode);
			} catch (EntityUnknownException cue) {
				logger.error(cue.getMessage());
			}
			regiondao.createRegion(key, regionInfos.getString(key), country);
		}
		return "tps : "+(System.currentTimeMillis()-t0)+"ms";
	}

	@Override
	public String initCities() {
		logger.info("Initialisation des cities");
		long t0 = System.currentTimeMillis();
		for (String key : cityInfos.keySet()) {
			String value = cityInfos.getString(key);
			StringTokenizer st = new StringTokenizer(value, ",");
			String countryCode = st.nextToken();
			String regionCode = st.nextToken();
			String cityLabel = st.nextToken();
			String postalCode = st.nextToken();
			String longitude = st.nextToken();
			String lattitude = st.nextToken();
			Region region = null;
			try {
				region = regiondao.find(countryCode + "," + regionCode);
			} catch (EntityUnknownException rue) {
				logger.error(rue.getMessage());
			}
			citydao.createCity(cityLabel, value, Integer.parseInt(longitude.replaceAll("\\.", "")), Integer.parseInt(lattitude.replaceAll("\\.", "")), postalCode, region);
		}
		return "tps : "+(System.currentTimeMillis()-t0)+"ms";
	}

	@Resource
	private TimerService timerService;
	private Boolean stopped = true;
	
	@Override
	public void startBroker() {
		if(stopped) {
			stopped = false;
			ScheduleExpression scheduleExp = new ScheduleExpression().second("*/3").minute("*").hour("*");
			TimerConfig config = new TimerConfig();
			config.setPersistent(false);
			config.setInfo("BROKER");
			timerService.createCalendarTimer(scheduleExp, config);	
		}
	}

	@Timeout
	protected void process(Timer timer) {
		if(!stopped) {
			logger.info("BROKER TRAITEMENT "+timer.getInfo());
		} else {
			logger.info("STOP BROKER "+timer.getInfo());
			timer.cancel();
		}
	}

	@Override
	public void stopBroker() {
		stopped = true;
	}
}
